<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html><head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>web.ctx (web.py)</title> 
  <link rel="stylesheet" type="text/css" href="/static/webpy-new.css"/> 
  <link rel="SHORTCUT ICON" href="/static/favicon.ico"/> 
</head><body> 
 
        <div id="header"><table class="header"><tr>
                <td class="logo"><a href="/" title="Home"><img src="/static/webpy.gif" alt="" /></a></td> 
<td class="blurb">&ldquo;Think about the ideal way to write a web app.<br />Write the code to make it happen.&rdquo; [<a href="/philosophy">more...</a>]</td> </tr>
</table>
        </div> 
        <div id="location"> 
                <a href="/">home</a> &gt; web.ctx
        </div> 
<div id="container"> 
<div id="sidebar">
<strong>get started:</strong>
<ul class="body">
  <li><a href="/install">install</a></li>
  <li><a href="/docs/0.3/tutorial">tutorial</a></li>
</ul>
<strong>learn more:</strong>
<ul class="body">
<li><a href="/docs/0.3/api">api reference</a></li>
<li><a href="/cookbook/">cookbook</a></li>
<li><a href="/src/">code examples</a></li>
</ul>

<strong>dive in:</strong>
<ul class="body"> 
<li><a href="https://github.com/webpy/webpy">source code</a></li>
<li><a href="http://groups.google.com/group/webpy/">mailing list</a></li>
<li><a href="https://github.com/webpy/webpy/issues">issue tracker</a></li>
</ul>
</div>

<div id="main"> 
<div id="content" class="body"> 
<h1>web.ctx</h1>

<h2>问题</h2>

<p>如何在代码中得到客户端信息？比如：来源页面(referring page)或是客户端浏览器类型</p>

<h2>解法</h2>

<p>使用web.ctx即可。首先讲一点架构的东西：web.ctx基于threadeddict类，又被叫做ThreadDict。这个类创建了一个类似字典(dictionary-like)的对象，对象中的值都是与线程id相对应的。这样做很妙,因为很多用户同时访问系统时，这个字典对象能做到仅为某一特定的HTTP请求提供数据(因为没有数据共享，所以对象是线程安全的)</p>

<p>web.ctx保存每个HTTP请求的特定信息，比如客户端环境变量。假设，我们想知道正在访问某页面的用户是从哪个网页跳转而来的：</p>

<h2>例子</h2>

<pre><code>class example:
    def GET(self):
        referer = web.ctx.env.get('HTTP_REFERER', 'http://google.com')
        raise web.seeother(referer)
</code></pre>

<p>上述代码用web.ctx.env获取HTTP_REFERER的值。如果HTTP＿REFERER不存在，就会将google.com做为默认值。接下来，用户就会被重定向回到之前的来源页面。</p>

<p>web.ctx另一个特性，是它可以被loadhook赋值。例如：当一个请求被处理时，会话(Session)就会被设置并保存在web.ctx中。由于web.ctx是线程安全的，所以我们可以象使用普通的python对象一样，来操作会话(Session)。</p>

<h2>'ctx'中的数据成员</h2>

<h3>Request</h3>

<ul>
<li><code>environ</code> 又被写做. <code>env</code> &ndash; 包含标准WSGI环境变量的字典。</li>
<li><code>home</code> &ndash; 应用的http根路径(译注：可以理解为应用的起始网址，协议＋站点域名＋应用所在路径)例：<em>http://example.org/admin</em></li>
<li><code>homedomain</code> &ndash; 应用所在站点(可以理解为协议＋域名) <em>http://example.org</em></li>
<li><code>homepath</code> &ndash; 当前应用所在的路径，例如： <em>/admin</em></li>
<li><code>host</code> &ndash; 主机名（域名）＋用户请求的端口（如果没有的话，就是默认的80端口），例如： <em>example.org</em>, <em>example.org:8080</em></li>
<li><code>ip</code> &ndash; 用户的IP地址，例如： <em>xxx.xxx.xxx.xxx</em></li>
<li><code>method</code> &ndash; 所用的HTTP方法，例如： <em>GET</em></li>
<li><code>path</code> &ndash; 用户请求路径，它是基于当前应用的相对路径。在子应用中，匹配外部应用的那部分网址将被去掉。例如：主应用在<code>code.py</code>中，而子应用在<code>admin.py</code>中。在<code>code.py</code>中, 我们将<code>/admin</code>关联到<code>admin.app</code>。 在<code>admin.py</code>中, 将<code>/stories</code>关联到<code>stories</code>类。在 <code>stories</code>中, <code>web.ctx.path</code>就是<code>/stories</code>, 而非<code>/admin/stories</code>。形如： <em>/articles/845</em></li>
<li><code>protocol</code> &ndash; 所用协议，例如： <em>https</em></li>
<li><code>query</code> &ndash; 跟在'？'字符后面的查询字符串。如果不存在查询参数，它就是一个空字符串。例如： <em>?fourlegs=good&amp;twolegs=bad</em></li>
<li><code>fullpath</code> 可以视为 <code>path + query</code> &ndash; 包含查询参数的请求路径，但不包括'homepath'。例如：<em>/articles/845?fourlegs=good&amp;twolegs=bad</em></li>
</ul>


<h3>Response</h3>

<ul>
<li><code>status</code> &ndash; HTTP状态码（默认是'200 OK') <em>401 Unauthorized 未经授权</em></li>
<li><code>headers</code> &ndash; 包含HTTP头信息(headers)的二元组列表。</li>
<li><code>output</code> &ndash; 包含响应实体的字符串。</li>
</ul>


<div style="clear: both;"></div> 
 
</div> 
 
</div> 
</div>
        <div id="footer"> 
    <p>started by <a style="color: gray;" href="http://www.aaronsw.com/">Aaron Swartz</a> (<a style="color: black;" href="mailto:webpy@aaronsw.com">webpy@aaronsw.com</a>)</p>

<p><a href="https://github.com/webpy/webpy.github.com/blob/master/cookbook/ctx.zh-cn.md">fork this page on GitHub</a></p>
</div> 
 
</body> 
</html> 
